class Solution {
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        // 1. 统计每门课的前置课程数量
        // 2. 统计每门课的后置课程(相当于有向图的出度数，相当于我学完了这门课可以学习哪些课)
        vector<int> preCount(numCourses);
        unordered_map<int, vector<int>> afterMap;

        for(vector<int> &course : prerequisites)
        {
            preCount[course[0]]++;
            afterMap[course[1]].push_back(course[0]);
        }

        // 如果前置课程数量为零，说明可以学
        queue<int> q;   // 保存可以学习的课程(即前置课程数量为0)
        for(int i = 0; i < numCourses; i++)
            if(preCount[i] == 0)
                q.push(i);

        int learned = 0;
        while(!q.empty())
        {
            int course = q.front();
            q.pop();

            learned++;

            // 遍历afterMap[course]，就是course的后置课程
            for(auto neighbors : afterMap[course])
            {
                preCount[neighbors]--;  // 代表这门课的前置数量学完了
                if(preCount[neighbors] == 0)
                    q.push(neighbors);  // 如果这门课的前置课程学完了，那这门也可以学习了，加入队列
            }
        }

        return learned == numCourses;
    }
};